from typing import Any

from client import es_client


async def get_iot_run_data(start_time, end_time, imei_list: list):
    # TODO: Implement the function to fetch IoT run data from Elasticsearch
    query = {
        "size": 0,
        "query": {
            "bool": {
                "must": [
                    {
                        "range": {
                            "startTime": {
                                "gte": start_time,
                                "lte": end_time
                            }
                        }
                    },
                    {"terms": {"imei": imei_list}}
                ],
            }
        },
        "aggs": {
            "by_imei": {
                "terms": {
                    "field": "imei",
                    "size": 10000
                },
                "aggs": {
                    "by_day": {
                        "date_histogram": {
                            "field": "createDate",
                            "calendar_interval": "day"

                        },
                        "aggs": {
                            "interval_ms_sum": {  # 原来名为 total_runtime_hours，实际是毫秒总和
                                "sum": {
                                    "field": "intervals"
                                }
                            },
                            "runtime_in_hours": {
                                "bucket_script": {
                                    "buckets_path": {
                                        "ms": "interval_ms_sum"
                                    },
                                    "script": "params.ms / (1000 * 60 * 60)"
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    es = await es_client.get_es_client()
    result = await es.search(index="i_iot_run", query=query)
    result = result['aggregations']['by_imei']['buckets']
    run_data = []
    for bucket in result:
        for day_bucket in bucket['by_day']['buckets']:
            if int(day_bucket.get('doc_count')) > 0:
                run_data.append({
                    'imei': bucket['key'],
                    'date': day_bucket['key_as_string'],
                    'runtime_hours': float(day_bucket['runtime_in_hours']['value']).__round__(2)
                })
    return run_data


async def get_iot_run_data_detail(start_time, end_time, term_list: list[dict] = None, terms_list: list[dict] = None):
    # TODO: Implement the function to fetch IoT run data from Elasticsearch
    if not term_list and not terms_list:
        return []
    query = {
        "size": 0,
        "_source": ['imei', 'intervals', 'createDate'],
        "query": {
            "bool": {
                "must": [
                    {
                        "range": {
                            "startTime": {
                                "gte": start_time,
                                "lte": end_time
                            }
                        }
                    }
                ]
            }
        },
        "aggs": {
            "by_day": {
                "date_histogram": {
                    "field": "createDate",
                    "calendar_interval": "1d",
                    "time_zone": "+08:00"
                },
                "aggs": {
                    "interval_hours": {
                        "sum": {
                            "script": {
                                "source": "doc['intervals'].value / 3600000.0"
                            }
                        }
                    }
                }
            }
        }
    }

    if term_list is not None:
        query['query']['bool']['must'].extend(term_list)
    if terms_list is not None:
        query['query']['bool']['must'].extend(terms_list)
    es = await es_client.get_es_client()
    return await es.search_documents(index="i_iot_run", query=query)


async def get_equipment_list(query_bool: dict):
    query_bool["must_not"] = [{"term": {"validState": {"value": 0}}}]
    query = {
        "size": 10000,
        "_source": ["imei", "member.name", "project.name", "city.name", "workAmount", "region.name", "workUnit",
                    "memberTypeName", "equipmentAlias", "createDate"],
        "query": {
            "bool": query_bool
        }
    }
    es = await es_client.get_es_client()
    result = await es.search(index="b_equipment_entity", query=query)
    equipment_info_list = []
    for item in result['hits']['hits']:
        equipment_info_list.append({
            'imei': item['_source']['imei'],
            'member_name': item['_source']['member']['name'],
            'region_name': item['_source']['region']['name'],
            'project_name': item['_source']['project']['name'],
            'city_name': item['_source']['city']['name'],
            'work_amount': item['_source']['workAmount'],
            'work_unit': item['_source']['workUnit'],
            'type': item['_source']['memberTypeName'],
            'createDate': item['_source']['createDate']
        })

    return equipment_info_list


async def get_work_rules(term: dict, start_time, end_time):
    # TODO: Implement the function to fetch IoT run data from Elasticsearch
    query = {
        "size": 1000,
        "_source": ['imei', 'categoryName', 'startTime', 'endTime', 'intervals', 'createDate'],
        "query": {
            "bool": {
                "must": [
                    {
                        "term": term
                    },
                    {
                        "range": {
                            "startTime": {
                                "gte": start_time,
                                "lte": end_time
                            }
                        }
                    }
                ]
            }
        }
    }
    es = await es_client.get_es_client()
    return await es.search_documents(index="i_iot_run", query=query)
